package com.android.bonn.fast.widget.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;

import com.android.bonn.fast.widget.R;

import androidx.constraintlayout.widget.ConstraintLayout;


/**
 * author huangyunlin@snqu.com
 * date 2018/12/13
 * description
 */
public class StateConstraintLayout extends ConstraintLayout {

    private int mStateErrorViewId;
    private int mStateLoadingViewId;
    private int mStateDefaultViewId;

    private LayoutInflater mInflater;


    public StateConstraintLayout(Context context) {
        super(context);
        init(null, 0);
    }

    public StateConstraintLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public StateConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, defStyleAttr);
    }

    private void init(AttributeSet attrs, int defStyleAttr) {
        //LayoutInflater.from(getContext()).inflate(R.layout.decor_child_view, this, true);
        TypedArray a = this.getContext().obtainStyledAttributes(attrs, R.styleable.StateToolBarConstraintLayout, defStyleAttr, 0);

        mStateErrorViewId = a.getResourceId(R.styleable.StateToolBarConstraintLayout_ctb_state_errorView, 0);
        mStateLoadingViewId = a.getResourceId(R.styleable.StateToolBarConstraintLayout_ctb_state_loadingView, 0);
        mStateDefaultViewId = a.getResourceId(R.styleable.StateToolBarConstraintLayout_ctb_state_defaultView, 0);

        mInflater = LayoutInflater.from(getContext());

        a.recycle();
    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    private LayoutParams layoutParams;

    private LayoutParams createStateViewLayoutParams(View dependView) {
        if (layoutParams == null) {
            layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, 0);
        }

        if (mEnableFullScreen) {
            layoutParams.width = LayoutParams.MATCH_PARENT;
            layoutParams.height = 0;
            layoutParams.topToTop = LayoutParams.PARENT_ID;
            layoutParams.bottomToBottom = LayoutParams.PARENT_ID;
            layoutParams.startToStart = LayoutParams.PARENT_ID;
            layoutParams.endToEnd = LayoutParams.PARENT_ID;
        } else {
            layoutParams.width = 0;
            layoutParams.height = 0;

            this.layoutParams.topToBottom = dependView.getId();
            this.layoutParams.bottomToBottom = LayoutParams.PARENT_ID;
            this.layoutParams.startToStart = LayoutParams.PARENT_ID;
            this.layoutParams.endToEnd = LayoutParams.PARENT_ID;

        }


        return layoutParams;
    }


    private View mLoadingView;
    private View mErrorView;
    private View mDefaultView;

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        cacheStateView.clear();
        removeAllViews();
    }

    public View getLoadingView() {
        return mLoadingView;
    }

    public View getErrorView() {
        return mErrorView;
    }

    public View getDefaultView() {
        return mDefaultView;
    }

    private final int STATE_ERROR = 0;
    private final int STATE_LOADING = 1;
    private final int STATE_DEFAULT = 2;
    private final int STATE_CONTENT = 3;

    private int mCurrentState = STATE_CONTENT;

    //是否显示全屏状态 view
    private boolean mEnableFullScreen = false;

    private ArrayMap<Integer, View> cacheStateView = new ArrayMap<>();

    /**
     * 开启全屏状态页面显示
     *
     * @param enableFullScreen true 开启全屏模式
     */
    public void setFullScreenStateView(boolean enableFullScreen) {
        mEnableFullScreen = enableFullScreen;
        layoutParams = null;
        cacheStateView.clear();
    }


    private void showAnimate(View view) {
        view.setAlpha(1);
        addView(view);
    }

    private void hideAnimate(final View view) {
        view.animate()
                .setDuration(200)
                .alpha(0)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        removeView(view);
                    }
                })
                .start();
    }

    private View buildView(int resId, View dependView) {

        View view = cacheStateView.get(resId);
        if (view == null) {
            view = mInflater.inflate(resId, this, false);
            view.setLayoutParams(createStateViewLayoutParams(dependView));
            cacheStateView.put(resId, view);
        }

        return view;
    }

    public void showDefaultView(boolean animate, View dependView) {
        if (mStateDefaultViewId > 0 && this.mCurrentState != STATE_DEFAULT) {
            clearStateView();
            this.mCurrentState = STATE_DEFAULT;
            mDefaultView = buildView(mStateDefaultViewId, dependView);
            if (animate) {
                showAnimate(mDefaultView);
            } else {
                addView(mDefaultView);
            }

        }
    }

    public void showErrorView(boolean animate, View dependView) {
        if (mStateErrorViewId > 0 && this.mCurrentState != STATE_ERROR) {
            clearStateView();
            this.mCurrentState = STATE_ERROR;
            mErrorView = buildView(mStateErrorViewId, dependView);
            if (animate) {
                showAnimate(mErrorView);
            } else {
                addView(mErrorView);
            }
        }

    }

    public void showLoadingView(boolean animate, View dependView) {
        if (mStateLoadingViewId > 0 && this.mCurrentState != STATE_LOADING) {
            clearStateView();
            this.mCurrentState = STATE_LOADING;
            mLoadingView = buildView(mStateLoadingViewId, dependView);
            if (animate) {
                showAnimate(mLoadingView);
            } else {
                addView(mLoadingView);
            }
        }

    }

    public void showDefaultView(View dependView) {
        showDefaultView(true, dependView);
    }

    public void showErrorView(View dependView) {
        showErrorView(true, dependView);
    }

    public void showLoadingView(View dependView) {
        showLoadingView(true, dependView);
    }

    public void showContent() {

        if (mCurrentState == STATE_ERROR) {
            hideAnimate(mErrorView);
        }
        if (mCurrentState == STATE_LOADING) {
            hideAnimate(mLoadingView);
        }

        if (mCurrentState == STATE_DEFAULT) {
            hideAnimate(mDefaultView);
        }

        mCurrentState = STATE_CONTENT;
    }


    @Override
    public void onViewAdded(View view) {
        super.onViewAdded(view);
    }

    @Override
    public void onViewRemoved(View view) {
        super.onViewRemoved(view);
    }

    private void clearStateView() {
        removeView(mErrorView);
        removeView(mLoadingView);
        removeView(mDefaultView);
    }

}
